package cn.wolfcode.job;

import cn.wolfcode.common.web.Result;
import cn.wolfcode.domain.Product;
import cn.wolfcode.domain.SeckillProduct;
import cn.wolfcode.domain.SeckillProductVo;
import cn.wolfcode.redis.JobRedisKey;
import cn.wolfcode.web.feign.ProductFeignApi;
import cn.wolfcode.web.feign.SeckillProductFeignApi;
import com.alibaba.fastjson.JSON;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

import static org.apache.zookeeper.ZooDefs.OpCode.getData;

/**
 * 用于处理每日秒杀商品缓存的定时任务
 */
@Component
@Setter
@Getter
@RefreshScope
@Slf4j
public class SecKillProductVOJob implements SimpleJob {
	@Value("${jobCron.seckillProductVOJob}")
	private String cron;
	@Autowired
	private StringRedisTemplate redisTemplate;
	@Autowired
	private SeckillProductFeignApi seckillProductFeignApi;
	@Autowired
	private ProductFeignApi productFeignApi;


	@Override
	public void execute(ShardingContext shardingContext) {
		doWork(shardingContext.getShardingParameter());
	}

	/** 按秒杀场次缓存数据到redis中 */
	private void doWork(String time) {
		//1.远程调用秒杀服务获取 List<SeckillProduct> seckillProducts
		Result<List<SeckillProduct>> ret = seckillProductFeignApi.queryTime(Integer.valueOf(time));
		if (ret != null && !ret.hasError()) {
			List<SeckillProduct> seckillProducts = ret.getData();

			//2.根据 list中存的商品 ids 远程调用商品服务查询 List<Product> products
			List<Long> idList = seckillProducts.stream().map(SeckillProduct::getProductId).collect(Collectors.toList());
			Result<List<Product>> result = productFeignApi.queryByIds(idList);
			if (result != null && !result.hasError()) {
				List<Product> products = result.getData();

				//3.把两个集合数据封装为 vos
				List<SeckillProductVo> vos = new ArrayList<>();
				for (int i = 0; i < products.size(); i++) {
					SeckillProductVo vo = new SeckillProductVo();

					// 先copy商品product的，因为redis中hashkey存的是seckillProduct的id
					BeanUtils.copyProperties(products.get(i), vo);
					BeanUtils.copyProperties(seckillProducts.get(i), vo);
					vos.add(vo);
				}

				//4.把 vos 数据缓存到 redis中
				if (vos.size() > 0) {
					String key = JobRedisKey.SECKILL_PRODUCT_LIST.getRealKey(time);
					Map<String,String> map = new HashMap<>();

					// hashKey为秒杀 id，hashVal为 vo的 JSON字符串
					vos.forEach(vo -> map.put(vo.getId().toString(), JSON.toJSONString(vo)));
					redisTemplate.opsForHash().putAll(key, map);
				}
			}
		}
	}
}
